package com.aiwiown.snackmq.console.web;

import com.aiwiown.snackmq.common.message.Message;
import com.aiwiown.snackmq.console.service.SnackMQAdminService;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.nio.charset.StandardCharsets;
import java.util.Map;

@Slf4j
@Controller
@RequestMapping("/tools")
public class ToolsController {

    @Autowired
    private SnackMQAdminService adminService;

    // 【改造】新增一个 DTO 用于在重定向上保存 Peek 表单的请求参数，使代码更清晰
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    static class PeekRequest {
        private String topic;
        private int partition;
        private long offset;
    }

    // 【新增】一个 DTO，用于安全地向视图传递 Peek 结果
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    static class PeekResultDTO {
        private String messageId;
        private String key;
        private String body;
        private java.util.Map<String, String> properties;

        public static PeekResultDTO fromMessage(Message message) {
            if (message == null) {
                return null;
            }
            return new PeekResultDTO(
                    String.valueOf(message.getMessageId()),
                    message.getKey(),
                    message.getBody() != null ? new String(message.getBody(), StandardCharsets.UTF_8) : "[Empty Body]",
                    message.getProperties()
            );
        }
    }
    @GetMapping
    public String toolsPage(Model model) {
        // 【改造】为 "Send Message" 表单准备数据，提升用户体验
        try {
            model.addAttribute("topics", adminService.listTopics());
            model.addAttribute("exchanges", adminService.listExchanges());
        } catch (Exception e) {
            model.addAttribute("formErrorMessage", "Failed to load topics/exchanges for form: " + e.getMessage());
        }
        if (!model.containsAttribute("peekRequest")) {
            model.addAttribute("peekRequest", new PeekRequest());
        }
        return "tools"; // 对应 tools.html
    }

    // 【修复】将路径从 /send-message 简化为 /send，以解决 404 问题并使 API 更简洁。
    @PostMapping("/send")
    public String sendMessage(@RequestParam String destination,
                              @RequestParam String destinationType,
                              @RequestParam(required = false) String routingKey,
                              @RequestParam(required = false) String messageKey,
                              @RequestParam String messageBody,
                              RedirectAttributes redirectAttributes) {
        try {
            boolean isExchange = "exchange".equals(destinationType);

            adminService.sendTestMessage(destination, isExchange, routingKey, messageKey, messageBody);

            redirectAttributes.addFlashAttribute("successMessage", "Message sent successfully to " + destinationType + " '" + destination + "'.");
        } catch (Exception e) {
            log.error("Failed to send test message", e);
            redirectAttributes.addFlashAttribute("errorMessage", "Failed to send message: " + e.getMessage());
        }
        return "redirect:/tools";
    }

    // 【修复】将路径从 /peek-message 修改为 /peek，以匹配前端 form 的 action
    @PostMapping("/peek")
    public String peekMessage(@RequestParam String topic,
                              @RequestParam int partition,
                              @RequestParam long offset,
                              RedirectAttributes redirectAttributes) { // 【改造】使用 RedirectAttributes 实现 PRG 模式
        try {
            Message peekedMessage = adminService.peekMessage(topic, partition, offset);
            if (peekedMessage != null) {
                // 【修复】将 Message 转换为对视图安全的 DTO
                PeekResultDTO resultDTO = PeekResultDTO.fromMessage(peekedMessage);
                redirectAttributes.addFlashAttribute("peekResult", resultDTO);
                redirectAttributes.addFlashAttribute("infoMessage", "Message found at offset " + offset + " in " + topic + "-" + partition);
            } else {
                redirectAttributes.addFlashAttribute("infoMessage", "No message found at the specified topic/partition/offset.");
            }
        } catch (Exception e) {
            log.error("Failed to peek message", e);
            redirectAttributes.addFlashAttribute("errorMessage", "Failed to peek message: " + e.getMessage());
        }

        // 【改造】将用户输入的请求参数也传回去，以便重新填充表单
        redirectAttributes.addFlashAttribute("peekRequest", new PeekRequest(topic, partition, offset));
        return "redirect:/tools"; // 【改造】返回重定向指令
    }

    // 【新增】诊断分区状态的端点
    @PostMapping("/diagnose")
    public String diagnosePartition(@RequestParam String topic,
                                   @RequestParam int partition,
                                   RedirectAttributes redirectAttributes) {
        try {
            Map<String, Object> diagnosis = adminService.diagnosePartition(topic, partition);
            redirectAttributes.addFlashAttribute("diagnosisResult", diagnosis);
            redirectAttributes.addFlashAttribute("infoMessage", "Diagnosis completed for " + topic + "-" + partition);
        } catch (Exception e) {
            log.error("Failed to diagnose partition", e);
            redirectAttributes.addFlashAttribute("errorMessage", "Failed to diagnose partition: " + e.getMessage());
        }
        return "redirect:/tools";
    }

    // 【新增】修复分区损坏段的端点
    @PostMapping("/repair")
    public String repairPartition(@RequestParam String topic,
                                 @RequestParam int partition,
                                 RedirectAttributes redirectAttributes) {
        try {
            adminService.repairPartition(topic, partition);
            redirectAttributes.addFlashAttribute("successMessage", "Partition repair completed for " + topic + "-" + partition);
        } catch (Exception e) {
            log.error("Failed to repair partition", e);
            redirectAttributes.addFlashAttribute("errorMessage", "Failed to repair partition: " + e.getMessage());
        }
        return "redirect:/tools";
    }

    // 【新增】手动修复分区段结构的端点
    @PostMapping("/manual-repair")
    public String manualRepairPartition(@RequestParam String topic,
                                       @RequestParam int partition,
                                       RedirectAttributes redirectAttributes) {
        try {
            adminService.manualRepairPartition(topic, partition);
            redirectAttributes.addFlashAttribute("successMessage", "Manual partition repair completed for " + topic + "-" + partition);
        } catch (Exception e) {
            log.error("Failed to manual repair partition", e);
            redirectAttributes.addFlashAttribute("errorMessage", "Failed to manual repair partition: " + e.getMessage());
        }
        return "redirect:/tools";
    }
}